<?php

namespace app\controller\Api\V1\Client;

use app\helper\Config;
use app\helper\GetProductInfo;
use app\helper\SmsVerifyCode;
use app\model\AutoTaskRecord;
use app\model\BoxUser;
use app\model\GameAuthorization;
use app\model\GameRechargeOrder;
use app\model\GameSell;
use app\model\GameSellConfig;
use app\model\GameSellDicker;
use app\model\GameSellOrder;
use app\model\User;
use Exception;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Shopwwi\WebmanAuth\Facade\JWT as JwtFace;
use support\Db;
use support\Log;
use support\Request;
use support\Response;
use Throwable;

class SellController
{

    protected SmsVerifyCode $smsVerifyCodeRe;
    protected Config $configRe;
    protected string $platform = 'game';
    protected array $paymentWay = [
        'alipay',
        'wechat',
        'trade-coin',  // 交易币
    ];


    public function __construct()
    {
        $this->smsVerifyCodeRe = SmsVerifyCode::getInstance();
        $this->configRe = Config::getInstance();

    }


    /**
     * 获取初始配置
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function Init(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
        ]);

        $userInfo = $request->userInfo;
        if (!$this->configRe->Get('system_test')) {
            if (empty($userInfo['name']) || empty($userInfo['id_number'])) {
                throw new Exception('请先实名认证', 500);
            }
            if (empty($userInfo['phone'])) {
                throw new Exception('请先绑定手机号', 500);
            }
        }

        $boxUserInfo = BoxUser::query()->where('user', $userInfo['ulid'])->where('state', 1)->first();
        if (!$boxUserInfo) {
            throw new Exception('用户不存在', 500);
        }

        $sellConfigInfo = GameSellConfig::query()->where('game', $request->input('game'))->latest()->first();
        if (!$sellConfigInfo) {
            throw new Exception('交易行未开启', 500);
        }
        if (empty($sellConfigInfo->allow_type)) {
            throw new Exception('交易行未开启', 500);
        }

        $sellConfigInfo = [
            'allow_type' => $sellConfigInfo->allow_type,
            'type_config' => $sellConfigInfo->type_config,
        ];

        return jsonRe([
            'data' => [
                'phone' => $userInfo['phone'] ?: '',
                'config' => $sellConfigInfo,
                'tip' => [
                    [
                        'title' => '买家须知',
                        'content' => '
                            1、因时间因素，部分数据发生变化(排行榜、称号到期、因游戏玩法调整导致属性改变等)，买家需理解并接受
                            2、点击【我要买】即可浏览本服在该平台上架待售的角色、货币及其他物品装备
                            3、点击购买按钮>提交订单>选择支付类型>完成支付 即可将商品购买至账号/角色下
                            4、购买角色时，要保证账号下对应收货区服有空角色栏，否则无法购买
                            5、成功购买角色后，小退至角色选择页，即可看到购买的角色,
                            6、成功购买的货币会直接出现在对应角色的背包里
                            7、不可以购买自己寄售的角色、货币及其他物品装备
                            8、一旦交易成功无故无法取消
                            9、商品图片只做参考，具体以试玩和收货为准
                            10、角色购买完成后请尽快确认收货
                            11、购买商品后请迅速收货，防止合区等原因导致角色、邮件被清理
                            12、退货会扣除本次交易的手续费
                        ',
                    ],
                    [
                        'title' => '卖家须知',
                        'content' => '
                            1、点击【我要卖】选择要寄售的角色、货币和物品装备,
                            2、价格符合系统标准，并经过玩家确认无误后寄售上架成功
                            3、寄售所得的交易币余额需使用官方指定的比奇盒子进行提现，交易币余额和人民币的比例为 1：1
                            4、每次寄售成功交易后所得费用需扣除手续费
                            5、出售的商品买家有选择是否收货的权益
                        '
                    ],
                    [
                        'title' => '如何取回寄售的商品?',
                        'content' => '
                            1、寄售的货币可直接在【我的货架】进行上下架处理
                            2、寄售的角色需下载官方指定的比奇盒子进行下架操作或者在游戏内角色选择页面进行取回操作
                        '
                    ],
                    [
                        'title' => '寄售所得的钱如何提现?',
                        'content' => '
                            1、提现需下载官方指定的比奇盒子进行提现
                            2、每次提现需扣除手续费
                        '
                    ],
                    [
                        'title' => '其他声明',
                        'content' => '
                            1、须按照试玩为准，交易成功不存在退货行为
                            2、交易订单存在异常行为，请在下单后24小时内反馈，平台方会根据实际情况对订单进行处理
                        '
                    ]
                ],
                'help' => [
                    "1、交易币和人民币的比例为1:1",
                    "2、交易币提现需下载官方游戏盒子",
                    "3、商品售卖成功或退货成功都会扣除服务费",
                    "4、商品退货，支付金额会以交易币的方式退回到支付的账号"
                ],
                'trade_coin' => [
                    'my' => $boxUserInfo->trade_coin ?? 0,
                    'unrecorded' => GameSellOrder::query()->where('seller', $userInfo['ulid'])->where('payment_state', 1)
                            ->where('sell_state', 3)->sum('payment_amount') ?? 0,
                ],
                'box_download_url' => $this->configRe->Get('box_download_url'),
            ]
        ]);
    }


    /**
     * 验证码验证
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function SmsVerify(Request $request): Response
    {

        requestValidator($request, [
            'code' => 'bail|required|string|size:6',
        ], [
            'code.required' => '请填写验证码',
            'code.string' => '验证码不正确',
            'code.size' => '验证码不正确',
        ]);

        $userInfo = $request->userInfo;

        $postParams = $request->post();
        $postParams['client_type'] = 'game_sell';
        $request->setPost($postParams);

        // 验证码验证
        if (!$this->configRe->Get('system_test')) {
            $this->smsVerifyCodeRe->VerifyCode($userInfo['phone'], $request->input('code'), $this->platform, 'operation-verify');
        }

        $token = JwtFace::make([
            'id' => $userInfo['id'],
            'ulid' => $userInfo['ulid'],
            'ip' => $request->getRealIp(),
            'client' => $this->platform,
            'scene' => 'SELL',
        ], 600);

        return jsonRe([
            'token' => $token->access_token,
        ]);
    }


    /**
     * 提交角色
     *
     * @param Request $request
     * @return Response
     * @throws Exception|Throwable
     */
    public function SellRole(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
            'price' => 'bail|required|decimal:2|min:0.01',
            'is_counter_offer' => 'bail|required|in:0,1',
            'is_designated_buyer' => 'bail|required|in:0,1',
            'designated_buyer' => 'bail|required_if:is_designated_buyer,1',
            'is_worry_free' => 'bail|required_if:is_counter_offer,1|in:0,1',
            'min_price' => 'bail|required_if:is_worry_free,1|decimal:2|min:0.01',
            'images' => 'bail|required|string',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
            'price.required' => '请填写售价',
            'price.decimal' => '售价格式不正确',
            'price.min' => '售价不能低于0.01',
            'is_counter_offer.required' => '请选择是否可以还价',
            'is_counter_offer.in' => '请选择是否可以还价',
            'is_designated_buyer.required' => '请选择是否指定购买人',
            'is_designated_buyer.in' => '请选择是否指定购买人',
            'designated_buyer.required_if' => '请选择购买人',
            'is_worry_free.required_if' => '请选择是否开启还价省心模式',
            'is_worry_free.in' => '请选择是否开启还价省心模式',
            'min_price.required_if' => '请填写还价最低同意价',
            'min_price.decimal' => '还价最低同意价格式不正确',
            'min_price.min' => '还价最低同意价不能低于0.01',
            'images.required' => '请上传截图',
            'images.string' => '截图格式不正确',
        ]);

        $gameInfo = GameAuthorization::query()->where('ulid', $request->input('game'))->where('state', 1)->latest()->first();
        if (!$gameInfo) {
            throw new Exception('游戏不存在', 500);
        }

        $sellConfigInfo = GameSellConfig::query()->where('game', $request->input('game'))->latest()->first();
        if (!$sellConfigInfo) {
            throw new Exception('交易行未开启', 500);
        }
        if (!in_array('role', $sellConfigInfo->allow_type)) {
            throw new Exception('未开启角色交易功能', 500);
        }
        $sellConfigInfo = [
            'type_config' => $sellConfigInfo->type_config,
        ];

        // 充值金额验证
        if (!empty($sellConfigInfo['type_config']['role']['min_recharge_amount'])) {
            $userRechargeAmount = GameRechargeOrder::query()->where('payment_state', 1)->where('game', $request->input('game'))
                ->where('area', $request->input('area'))->where('role_id', $request->input('role_id'))->sum('payment_amount');
            if ($userRechargeAmount < $sellConfigInfo['type_config']['role']['min_recharge_amount']) {
                throw new Exception('禁止交易，当前角色充值金额低于' . $sellConfigInfo['type_config']['role']['min_recharge_amount'], 500);
            }
        }

        $userInfo = $request->userInfo;

        // 两次售卖间隔大于5分钟
        $latestSellRecord = GameSell::query()->where('user', $userInfo['ulid'])->where('game', $request->input('game'))
            ->where('area', $request->input('area'))->where('role_id', $request->input('role_id'))
            ->where('role_name', $request->input('role_name'))->where('type', 1)->latest()->first();
        if ($latestSellRecord) {
            if ($latestSellRecord->state !== 0) {
                throw new Exception('当前角色已售卖', 500);
            }
            if (strtotime($latestSellRecord->created_at) + 300 >= time()) {
                throw new Exception('同一角色5分钟之内不能多次售卖', 500);
            }
        }

        $designatedBuyerUlid = null;
        if (!empty($request->input('designated_buyer'))) {
            $designatedBuyerInfo = User::query()->where('account', $request->input('designated_buyer'))->latest()->first();
            if (!$designatedBuyerInfo) {
                throw new Exception('指定购买人不存在', 500);
            }
            if ($designatedBuyerInfo->ulid === $userInfo['ulid']) {
                throw new Exception('购买人不能指定自己', 500);
            }
            if ($request->input('is_designated_buyer')) {
                $designatedBuyerUlid = $designatedBuyerInfo->ulid;
            }
        }

        if ($request->input('price') < $sellConfigInfo['type_config']['role']['min_price']) {
            throw new Exception('售价不能低于' . $sellConfigInfo['type_config']['role']['min_price'], 500);
        }
        $serviceCharge = max(0, bcmul($sellConfigInfo['type_config']['role']['service_charge_ratio'], $request->input('price'), 2));
        if (!empty($request->input('min_price'))) {
            if ($request->input('min_price') > $request->input('price')) {
                throw new Exception('还价最低同意价不能高于售价', 500);
            }
            if ($request->input('min_price') < $sellConfigInfo['type_config']['role']['min_price']) {
                throw new Exception('还价最低同意价不能低于' . $sellConfigInfo['type_config']['role']['min_price'], 500);
            }
            if ($serviceCharge > $request->input('min_price')) {
                throw new Exception('还价最低同意价不能低于手续费', 500);
            }
        }

        Db::connection('biqi_game')->beginTransaction();
        try {
            $gameSellInfo = GameSell::query()->updateOrCreate([
                'user' => $userInfo['ulid'],
                'game' => $request->input('game'),
                'area' => $request->input('area'),
                'role_id' => $request->input('role_id'),
                'type' => 1,
            ], [
                'role_name' => $request->input('role_name'),
                'price' => $request->input('price'),
                'service_charge_ratio' => $sellConfigInfo['type_config']['role']['service_charge_ratio'],
                'is_counter_offer' => $request->input('is_counter_offer'),
                'is_designated_buyer' => $request->input('is_designated_buyer'),
                'designated_buyer' => $designatedBuyerUlid,
                'is_worry_free' => $request->input('is_worry_free'),
                'min_price' => $request->input('min_price') ?: '0.00',
                'content' => [
                    'images' => json_decode($request->input('images'), true),
                ],
                'state' => 0,
                'remark' => null,
            ]);

            $getProductPlatform = GetProductInfo::getInstance();
            $publicPlatformInfo = $getProductPlatform->GetPublicPlatform();

            AutoTaskRecord::query()->create([
                'label' => 'area-command',
                'params' => json_encode([
                    'cmd' => 'Transaction',
                    'data' => [
                        'script' => 'TradePlayerApplyFor',
                        'ulid' => $gameSellInfo->ulid,
                        'mch_id' => $gameInfo->merchant,
                        'game_id' => $request->input('game'),
                        'area_id' => $request->input('area'),
                        'regionid' => $request->input('area'),
                        'chrid' => $request->input('role_id'),
                        'chrname' => $request->input('role_name'),
                        'account' => $userInfo['account'],
                        'level' => $sellConfigInfo['type_config']['role']['min_level'] ?: 0,
                    ],
                    'callback_url' => $publicPlatformInfo['api_url'] . '/api/v1/server-callback/sell-role',
                    'task_time' => date('Y-m-d H:i:s'),
                ]),
                'run_time' => time(),
                'state' => 0,
            ]);
        } catch (Exception $e) {
            Db::connection('biqi_game')->rollBack();

            // 删除云资源
            $delFileList = [];
            foreach (json_decode($request->input('images'), true) as $item) {
                $delFileList[] = [
                    'name' => $item,
                    'is_folder' => false,
                ];
            }
            AutoTaskRecord::query()->create([
                'label' => 'delete-cloud-file',
                'params' => json_encode($delFileList),
                'run_time' => time(),
                'state' => 0,
            ]);

            Log::info('提交失败: ' . $e);
            throw new Exception('提交失败', 500);
        }

        Db::connection('biqi_game')->commit();

        return jsonRe([
            'sell' => $gameSellInfo->ulid,
        ]);

    }


    /**
     * 提交角色结果查询
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function SellRoleResult(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
            'sell' => 'bail|required|exists:app\\model\\GameSell,ulid,deleted_at,NULL',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
            'sell.required' => '请选择交易',
            'sell.exists' => '交易不存在',
        ]);

        $userInfo = $request->userInfo;

        $gameInfo = GameAuthorization::query()->where('ulid', $request->input('game'))->where('state', 1)->latest()->first();
        if (!$gameInfo) {
            throw new Exception('游戏不存在', 500);
        }

        $sellInfo = GameSell::query()->where('user', $userInfo['ulid'])->where('ulid', $request->input('sell'))->latest()->first();
        if (!$sellInfo) {
            throw new Exception('交易不存在', 500);
        }

        if (!in_array($sellInfo->state, [0, 1])) {
            throw new Exception('角色上架失败', 500);
        }

        if ($sellInfo->state === 0 && empty($sellInfo->remark)) {
            throw new Exception('角色上架中', 500);
        }

        return jsonRe([
            'state' => $sellInfo->state === 1,
        ], 200, $sellInfo->state === 1 ? '' : ($sellInfo->remark ?: ''));

    }


    /**
     * 交易列表
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function List(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'type' => 'bail|required|in:0,1,2',  // 0全部 1角色 2货币
            'is_designate_me' => 'bail|required|in:0,1',  // 0不指定我 1指定我
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'type.required' => '请选择类型',
            'type.in' => '类型不支持',
            'is_designate_me.required' => '请选择指定状态',
            'is_designate_me.in' => '指定状态不支持',
        ]);

        $userInfo = $request->userInfo;
        $noPage = max(1, $request->input('no_page') ?? 1);
        $pageSize = max(1, $request->input('page_size') ?? 10);

        $listSql = GameSell::query()->where('state', 1)->whereDoesntHave('GameSellOrderBind', function (Builder $query) {
            $query->whereIn('payment_state', [1, 5]);
        })->where('game', $request->input('game'))->where('area', $request->input('area'));

        if (!empty($request->input('type'))) {
            $listSql->where('type', $request->input('type'));
        }
        if ($request->input('is_designate_me')) {
            $listSql->where('designated_buyer', $userInfo['ulid']);
        }
        if ($request->input('role_name')) {
            $listSql->where('role_name', 'like', '%' . $request->input('role_name') . '%');
        }
        if ($request->input('occupation')) {
            $listSql->whereJsonContains('content->occupation', $request->input('occupation'));
        }
        if (!empty($request->input('sort'))) {
            foreach ($request->input('sort') as $sortKey => $sortValue) {
                if (in_array($sortKey, ['price', 'level'])) {
                    if ($sortValue === 'desc') {
                        $listSql->latest($sortKey);
                    }
                    if ($sortValue === 'asc') {
                        $listSql->oldest($sortKey);
                    }
                }
            }
        }
        $list = $listSql->latest('created_at')->skip(($noPage - 1) * $pageSize)->take($pageSize)->get()->map(function ($row) {
            return [
                'ulid' => $row['ulid'],
                'role_id' => $row['role_id'],
                'role_name' => $row['role_name'],
                'type' => $row['type'],
                'level' => $row['level'],
                'price' => $row['price'],
                'sex' => $row['content']['sex'] ?? '',
                'occupation' => $row['content']['occupation'] ?? '',
                'is_counter_offer' => $row['is_counter_offer'],
                'min_price' => $row['min_price'],
            ];
        })->toArray();

        return jsonRe([
            'list' => $list,
            'pagination' => [
                'no_page' => $noPage,
                'page_size' => $pageSize,
                'total_page' => ceil((clone $listSql)->count() / $pageSize),
                'total_count' => (clone $listSql)->count(),
            ]
        ]);
    }


    /**
     * 交易记录
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function Record(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
        ]);

        $noPage = max(1, $request->input('no_page') ?? 1);
        $pageSize = max(1, $request->input('page_size') ?? 10);

        $listSql = GameSellOrder::query()->where('payment_state', 5)->where('sell_state', 1)->latest();

        $list = (clone $listSql)->skip(($noPage - 1) * $pageSize)->take($pageSize)->get()->map(function ($row) {
            return '玩家' . $row->Seller->account . '交易成功，回血' . bcsub($row['payment_amount'], $row['service_charge'], 2) . '元';
        })->toArray();

        return jsonRe([
            'list' => $list,
            'pagination' => [
                'no_page' => $noPage,
                'page_size' => $pageSize,
                'total_page' => ceil((clone $listSql)->count() / $pageSize),
                'total_count' => (clone $listSql)->count(),
            ]
        ]);

    }


    /**
     * 还价
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function Dicker(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
            'sell' => 'bail|required|exists:app\\model\\GameSell,ulid,state,1,deleted_at,NULL',
            'price' => 'bail|required|decimal:2|min:0.01',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
            'sell.required' => '请选择交易',
            'sell.exists' => '交易不存在',
            'price.required' => '请填写还价金额',
            'price.decimal' => '还价金额格式不正确',
            'price.min' => '还价金额不能低于0.01'
        ]);

        $userInfo = $request->userInfo;

        $sellInfo = GameSell::query()->where('ulid', $request->input('sell'))->where('state', 1)
            ->where('user', '!=', $userInfo['ulid'])->latest()->first();
        if (!$sellInfo) {
            throw new Exception('交易不存在', 500);
        }
        if (!$sellInfo->is_counter_offer) {
            throw new Exception('当前交易不支持还价', 500);
        }
        if ($request->input('price') >= $sellInfo->price) {
            throw new Exception('还价不能高于售价', 500);
        }

        // 多次还价不能高于上一次还价
        $latestDicker = GameSellDicker::query()->where('user', $userInfo['ulid'])->where('sell', $sellInfo->ulid)->latest()->first();
        if ($latestDicker && $request->input('price') >= $latestDicker->price) {
            throw new Exception('还价金额只能低于上一次还价金额', 500);
        }

        $payInfo = [];
        try {
            $dickerInfo = GameSellDicker::query()->create([
                'user' => $userInfo['ulid'],
                'sell' => $sellInfo->ulid,
                'price' => $request->input('price'),
            ]);

            // 如果开启还价省心模式
            if ($sellInfo->is_worry_free && !empty($sellInfo->min_price)) {
                if ($sellInfo->min_price >= $request->input('price')) {
                    $getProductPlatform = GetProductInfo::getInstance();
                    $payPlatformInfo = $getProductPlatform->GetPayPlatform();
                    if (empty($payPlatformInfo['api_url'])) {
                        throw new Exception('未配置支付平台', 500);
                    }

                    // 走购买流程
                    $payInfo = [
                        'payment_url' => $payPlatformInfo['api_url'],
                        'payment_method' => $this->paymentWay,
                        'dicker' => $dickerInfo->ulid,
                    ];
                }
            }
        } catch (Exception) {
            throw new Exception('还价失败', 500);
        }

        return jsonRe([
            'pay_info' => $payInfo,
        ]);

    }


    /**
     * 购买
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function Buy(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
            'sell' => 'bail|required|exists:app\\model\\GameSell,ulid,state,1,deleted_at,NULL',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
            'sell.required' => '请选择交易',
            'sell.exists' => '交易不存在',
        ]);

        $userInfo = $request->userInfo;

        $sellInfo = GameSell::query()->where('ulid', $request->input('sell'))->where('state', 1)->latest()->first();
        if (!$sellInfo) {
            throw new Exception('交易不存在', 500);
        }

        if ($sellInfo->user == $userInfo['ulid']) {
            throw new Exception('不能购买自己出售的商品', 500);
        }

        $getProductPlatform = GetProductInfo::getInstance();
        $payPlatformInfo = $getProductPlatform->GetPayPlatform();
        if (empty($payPlatformInfo['api_url'])) {
            throw new Exception('未配置支付平台', 500);
        }

        return jsonRe([
            'pay_info' => [
                'payment_url' => $payPlatformInfo['api_url'],
                'payment_method' => $this->paymentWay,
                'dicker' => '',
                'countdown' => 60,
            ],
        ]);

    }


    /**
     * 取回角色验证
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function RetrieveRoleVerify(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
        ]);

        $userInfo = $request->userInfo;

        $sellInfo = GameSell::query()->where('user', $userInfo['ulid'])->where('game', $request->input('game'))
            ->where('area', $request->input('area'))->where('role_id', $request->input('role_id'))
            ->where('role_name', $request->input('role_name'))->where('type', 1)->where('state', 1)
            ->latest()->first();
        if (!$sellInfo) {
            throw new Exception('交易不存在', 500);
        }

        return jsonRe([
            'phone' => $userInfo['phone'] ?: '',
            'sell' => $sellInfo->ulid,
        ]);

    }


    /**
     * 取回角色
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function RetrieveRole(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
            'sell' => 'bail|required|exists:app\\model\\GameSell,ulid,state,1,deleted_at,NULL',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
            'sell.required' => '请选择交易',
            'sell.exists' => '交易不存在',
        ]);

        $userInfo = $request->userInfo;

        $gameInfo = GameAuthorization::query()->where('ulid', $request->input('game'))->where('state', 1)->latest()->first();
        if (!$gameInfo) {
            throw new Exception('游戏不存在', 500);
        }

        $sellInfo = GameSell::query()->where('user', $userInfo['ulid'])->where('ulid', $request->input('sell'))
            ->where('type', 1)->where('state', 1)->latest()->first();
        if (!$sellInfo) {
            throw new Exception('交易不存在', 500);
        }

        $getProductPlatform = GetProductInfo::getInstance();
        $publicPlatformInfo = $getProductPlatform->GetPublicPlatform();

        try {
            AutoTaskRecord::query()->create([
                'label' => 'area-command',
                'params' => json_encode([
                    'cmd' => 'Transaction',
                    'data' => [
                        'script' => 'TradePlayerRemove',
                        'ulid' => $sellInfo->ulid,
                        'mch_id' => $gameInfo->merchant,
                        'game_id' => $request->input('game'),
                        'area_id' => $request->input('area'),
                        'regionid' => $request->input('area'),
                        'chrid' => $sellInfo->role_id,
                        'tradeid' => $sellInfo->content['tradeid'],
                    ],
                    'callback_url' => $publicPlatformInfo['api_url'] . '/api/v1/server-callback/retrieve-role',
                    'task_time' => date('Y-m-d H:i:s'),
                ]),
                'run_time' => time(),
                'state' => 0,
            ]);
        } catch (Exception $e) {
            Log::info('取回角色失败:' . $e);
            throw new Exception('取回角色失败', 500);
        }

        return jsonRe();

    }


    /**
     * 取回角色结果查询
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function RetrieveRoleResult(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
            'sell' => 'bail|required|exists:app\\model\\GameSell,ulid,deleted_at,NULL',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
            'sell.required' => '请选择交易',
            'sell.exists' => '交易不存在',
        ]);

        $userInfo = $request->userInfo;

        $gameInfo = GameAuthorization::query()->where('ulid', $request->input('game'))->where('state', 1)->latest()->first();
        if (!$gameInfo) {
            throw new Exception('游戏不存在', 500);
        }

        $sellInfo = GameSell::query()->where('user', $userInfo['ulid'])->where('ulid', $request->input('sell'))->latest()->first();
        if (!$sellInfo) {
            throw new Exception('交易不存在', 500);
        }

        if ($sellInfo->state !== 0) {
            throw new Exception('角色取回失败', 500);
        }

        return jsonRe();

    }


    /**
     * 角色收货验证
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function ReceiveRoleVerify(Request $request): Response
    {
        Log::info($request->getRealIp() . '角色收货验证: ' . $request->url(), $request->all());
        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
        ]);

        $userInfo = $request->userInfo;

        $sellInfo = GameSell::query()->where('game', $request->input('game'))->where('area', $request->input('area'))
            ->where('role_id', $request->input('role_id'))->where('role_name', $request->input('role_name'))
            ->where('type', 1)->where('state', 2)->latest()->first();
        if (!$sellInfo) {
            throw new Exception('交易不存在', 500);
        }
        $sellOrderInfo = GameSellOrder::query()->where('sell', $sellInfo->ulid)->where('user', $request->user)->where('payment_state', 1)
            ->where('sell_state', 3)->latest()->first();
        if (!$sellOrderInfo) {
            throw new Exception('交易订单不存在', 500);
        }

        return jsonRe([
            'phone' => $userInfo['phone'] ?: '',
            'order' => $sellOrderInfo->ulid,
        ]);

    }


    /**
     * 角色收货
     *
     * @param Request $request
     * @return Response
     * @throws Throwable
     */
    public function ReceiveRole(Request $request): Response
    {

        requestValidator($request, [
            'ulid' => 'bail|required|exists:app\\model\\GameSellOrder,ulid,payment_state,1,sell_state,3,deleted_at,NULL',
        ], [
            'ulid.required' => '请选择订单',
            'ulid.exists' => '订单不存在',
        ]);

        $sellOrderInfo = GameSellOrder::query()->has('GameSellBind')->where('ulid', $request->input('ulid'))->where('user', $request->user)
            ->where('payment_state', 1)->where('sell_state', 3)->latest()->first();
        if (!$sellOrderInfo) {
            throw new Exception('订单不存在', 500);
        }

        Db::connection('biqi_game')->beginTransaction();

        try {
            $sellOrderInfo->update([
                'sell_state' => 1,
                'payment_state' => 5,
            ]);

            $getProductPlatform = GetProductInfo::getInstance();
            $publicPlatformInfo = $getProductPlatform->GetPublicPlatform();

            AutoTaskRecord::create([
                'label' => 'area-command',
                'params' => json_encode([
                    'cmd' => 'Transaction',
                    'data' => [
                        'script' => 'TradeAccept',
                        'ulid' => $sellOrderInfo->sell,
                        'mch_id' => $sellOrderInfo->GameSellBind->GameAuthorizationBind->merchant,
                        'game_id' => $sellOrderInfo->GameSellBind->game,
                        'area_id' => $sellOrderInfo->GameSellBind->area,
                        'regionid' => $sellOrderInfo->GameSellBind->area,
                        'chrid' => $sellOrderInfo->GameSellBind->role_id,
                        'tradeid' => $sellOrderInfo->GameSellBind->content['tradeid'],
                        'order_number' => $sellOrderInfo->order_number,
                    ],
                    'callback_url' => $publicPlatformInfo['api_url'] . '/api/v1/server-callback/sell-receipt',
                    'task_time' => date('Y-m-d H:i:s'),
                ]),
                'run_time' => time(),
                'state' => 0,
            ]);
        } catch (Exception) {
            Db::connection('biqi_game')->rollBack();
            throw new Exception('操作失败', 500);
        }

        Db::connection('biqi_game')->commit();

        return jsonRe();

    }


    /**
     * 角色退货验证
     *
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function ReturnRoleVerify(Request $request): Response
    {

        requestValidator($request, [
            'game' => 'bail|required|exists:app\\model\\GameAuthorization,ulid,state,1,deleted_at,NULL',
            'area' => 'bail|required|exists:app\\model\\DistrictService,ulid,state,1,deleted_at,NULL',
            'role_id' => 'bail|required|string',
            'role_name' => 'bail|required|string',
        ], [
            'game.required' => '游戏不能为空',
            'game.exists' => '游戏不存在',
            'area.required' => '区服不能为空',
            'area.exists' => '区服不存在',
            'role_id.required' => '请选择角色',
            'role_id.string' => '角色ID不正确',
            'role_name.required' => '请选择角色',
            'role_name.string' => '角色名称不正确',
        ]);

        $userInfo = $request->userInfo;

        $sellInfo = GameSell::query()->where('game', $request->input('game'))->where('area', $request->input('area'))
            ->where('role_id', $request->input('role_id'))->where('role_name', $request->input('role_name'))
            ->where('type', 1)->where('state', 2)->latest()->first();
        if (!$sellInfo) {
            throw new Exception('交易不存在', 500);
        }
        $sellOrderInfo = GameSellOrder::query()->where('sell', $sellInfo->ulid)->where('payment_state', 1)->where('user', $request->user)
            ->where('sell_state', 3)->latest()->first();
        if (!$sellOrderInfo) {
            throw new Exception('交易订单不存在', 500);
        }

        return jsonRe([
            'phone' => $userInfo['phone'] ?: '',
            'order' => $sellOrderInfo->ulid,
        ]);

    }


    /**
     * 角色退货
     *
     * @param Request $request
     * @return Response
     * @throws Throwable
     */
    public function ReturnRole(Request $request): Response
    {

        requestValidator($request, [
            'ulid' => 'bail|required|exists:app\\model\\GameSellOrder,ulid,payment_state,1,sell_state,3,deleted_at,NULL',
        ], [
            'ulid.required' => '请选择订单',
            'ulid.exists' => '订单不存在',
        ]);

        $sellOrderInfo = GameSellOrder::query()->has('GameSellBind')->where('ulid', $request->input('ulid'))->where('user', $request->user)
            ->where('payment_state', 1)->where('sell_state', 3)->latest()->first();
        if (!$sellOrderInfo) {
            throw new Exception('订单不存在', 500);
        }

        Db::connection('biqi_game')->beginTransaction();

        try {
            $sellOrderInfo->update([
                'sell_state' => 1,
                'payment_state' => 3,
            ]);

            $getProductPlatform = GetProductInfo::getInstance();
            $publicPlatformInfo = $getProductPlatform->GetPublicPlatform();

            AutoTaskRecord::create([
                'label' => 'area-command',
                'params' => json_encode([
                    'cmd' => 'Transaction',
                    'data' => [
                        'script' => 'TradePlayerRollback',
                        'ulid' => $sellOrderInfo->sell,
                        'mch_id' => $sellOrderInfo->GameSellBind->GameAuthorizationBind->merchant,
                        'game_id' => $sellOrderInfo->GameSellBind->game,
                        'area_id' => $sellOrderInfo->GameSellBind->area,
                        'regionid' => $sellOrderInfo->GameSellBind->area,
                        'chrid' => $sellOrderInfo->GameSellBind->role_id,
                        'tradeid' => $sellOrderInfo->GameSellBind->content['tradeid'],
                        'order_number' => $sellOrderInfo->order_number,
                    ],
                    'callback_url' => $publicPlatformInfo['api_url'] . '/api/v1/server-callback/sell-return',
                    'task_time' => date('Y-m-d H:i:s'),
                ]),
                'run_time' => time(),
                'state' => 0,
            ]);
        } catch (Exception) {
            Db::connection('biqi_game')->rollBack();
            throw new Exception('操作失败', 500);
        }

        Db::connection('biqi_game')->commit();

        return jsonRe();

    }

}
